package cn.maihe.elg.operation.centers.epoint.handler.service;

import cn.maihe.elg.operation.centers.epoint.config.EpointCenterInfosConfig;
import cn.maihe.elg.operation.centers.epoint.dto.EpointBaseRespDTO;
import cn.maihe.elg.operation.centers.epoint.dto.handler.EpointQuitApplyReq;
import cn.maihe.elg.operation.centers.epoint.handler.EpointCenterTradeService;
import cn.maihe.elg.operation.centers.supports.CenterTradeContext;
import cn.maihe.elg.operation.centers.supports.annotation.CenterTradeService;
import cn.maihe.elg.operation.model.enums.*;
import cn.maihe.elg.operation.repository.entity.AcceptOrderInfoDO;
import cn.maihe.elg.operation.repository.entity.ProjectInfoDO;
import cn.maihe.elg.operation.repository.entity.RevokeOrderInfo;
import cn.maihe.elg.operation.service.business.ProjectInfoService;
import cn.maihe.elg.operation.service.order.AcceptOrderInfoService;
import cn.maihe.elg.operation.service.order.RevokeOrderInfoService;
import cn.maihe.elg.operation.utils.IdGenerate;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;

/**
 * @Description 放弃申请通知接口 ： 若未确认支付则允许放弃申请，若已确认支付者不允许发起申请
 * @Author caixh
 * @Date 2021/7/14.
 */
@CenterTradeService(
        provider = CenterProviderEnum.EPOINT,
        centerNo = CenterNoEnum.NANPING,
        tradeType = TradeType.quitapply,
        reqClass = EpointQuitApplyReq.class,
        respClass = EpointBaseRespDTO.class
)
@Slf4j
public class NPEpointQuitApplyService extends EpointCenterTradeService<EpointQuitApplyReq, EpointBaseRespDTO> {

    @Resource
    private AcceptOrderInfoService acceptOrderInfoService;
    @Resource
    private ProjectInfoService projectInfoService;
    @Resource
    private RevokeOrderInfoService revokeOrderInfoService;

    public NPEpointQuitApplyService(EpointCenterInfosConfig centerInfosConfig) {
        super(centerInfosConfig);
    }

    /**
     * 具体业务处理
     *
     * @param context
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public EpointBaseRespDTO processService(CenterTradeContext<EpointQuitApplyReq, EpointBaseRespDTO> context) {

        EpointQuitApplyReq req = context.getReq();
        Long centerId = context.getCenterId();
        Long orgId = context.getOrgId();
        String revokeNo = req.getBaohanno();

        AcceptOrderInfoDO orderInfoDO = acceptOrderInfoService.getByGuaranteeNo(centerId, orgId, req.getBaohanno());
        if (orderInfoDO == null) {
            return EpointBaseRespDTO.error("查无此投保申请记录");
        }
        RevokeFlagEnum flagEnum = RevokeFlagEnum.resolve(orderInfoDO.getRevokeFlag());
        if (flagEnum == RevokeFlagEnum.SUCCESS || flagEnum == RevokeFlagEnum.FAILURE) {
            return EpointBaseRespDTO.error("退保状态为[" + flagEnum + "]，不能再申请退保");
        }
        if (flagEnum == RevokeFlagEnum.PROCESSING) {
            return EpointBaseRespDTO.error("退保审核中，请耐心等待审核结果");
        }
        if (flagEnum != RevokeFlagEnum.INIT) {
            return EpointBaseRespDTO.error("退保状态不是待退保状态，不能申请退保");
        }

        if (orderInfoDO.getStatus() == AcceptOrderStatus.FINISH.getStatus()) {
            return EpointBaseRespDTO.error("保函已完成，不能退保申请");
        }
        if (orderInfoDO.getStatus() == AcceptOrderStatus.CANCEL.getStatus()) {
            return EpointBaseRespDTO.error("保函已取消，不能退保申请");
        }
        if (orderInfoDO.getStatus() != AcceptOrderStatus.HAS_OUT_GUARANTEE.getStatus()) {
            return EpointBaseRespDTO.error("已出函状态才能发起退保，未出函前可调用放弃投保申请");
        }


        AcceptOrderInfoDO updateOrderInfo = AcceptOrderInfoDO.builder().id(orderInfoDO.getId())
                .status(AcceptOrderStatus.REVOKE_PROCESSING.getStatus()).revokeTime(new Date())
                .revokeFlag(RevokeFlagEnum.PROCESSING.getFlag()).remark(req.getReason()).build();
        acceptOrderInfoService.updateById(updateOrderInfo);

        ProjectInfoDO project = projectInfoService.selectById(orderInfoDO.getProjectId());

        RevokeOrderInfo revokeOrderInfo = RevokeOrderInfo.builder()
                .id(IdGenerate.getId())
                .centerId(centerId)
                .orgId(orgId)
                //通过保函编号关联受理订单号
                .revokeNo(revokeNo)
                .note(req.getReason())
                //备注字段存储 业务流水号
                .remark(req.getApplyno())
                .projectCode(project.getProjectCode()).projectName(orderInfoDO.getProjectName())
                .sectionCode(project.getSectionCode()).sectionName(orderInfoDO.getSectionName())
                .tenderer(project.getTenderer()).status(0)
                .build();

        revokeOrderInfoService.saveRevokeOrderInfo(revokeOrderInfo);

        return EpointBaseRespDTO.success("退保申请已受理,请耐心等待审核结果通知");
    }
}
